#include <stdlib.h>
#include <stdio.h>
#include <time.h>

#include "DemoDateTime.h"
#include "DemoBranch.h"

BOOL isLeapYear(int year) {
    
    if(0 == year%400) {
        // 能被400整除的年份是闰年
        return YES;
    }
    
    if(0 == year%100) {
        // 不能被400整除 但是能被100整除的年份是 平年
        return NO;
        
    } else if(0 == year%4) {
        // 不能被100整除，但是能被4整除的年份是 润年
        return YES;
        
    } else {
    
        // 其他的年份是平年
        return NO;
    }
}

int dayNumOfYear(int year, int month) {

    int dayNum = 0;
    
    switch (month) {
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
            dayNum = 31;
            break;
        case 4:
        case 6:
        case 9:
        case 11:
            dayNum = 30;
            break;
        case 2:
            dayNum = isLeapYear(year) ? 29 : 28;
            break;
        default:
            dayNum = 0;
            break;
    }
    
    return dayNum;
    
}

/**
 2019年1月1日 是周二，以此为基准，计算一个日期对应的星期

 @param year 闭区间[-2000, 4000]
 @param month 1base
 @param day 1base
 @return 1base week day, -1 if not a valid day
 */
int computeWeekDayOfYear(int year, int month, int day) {
    //

     //入参校验
    if( ! (year >= -2000 && year<=4000)) {
        // 年数字不合法
        return -1;
    }

    int monthDayNum = dayNumOfYear(year, month);
    if(0 == monthDayNum) {
        // 月数字不合法
        return -1;
    }
    
    if(day < 1 || day >monthDayNum) {
         // 日数字不合法
        return -1;
    }
    
    // 计算和基准日期的差值, 2019年1月1日 是周二
    const int baseYear = 2019;
    const int baseMonth = 1;
    const int baseDay = 1;
    const int baseWeekDay = 1; // 周二，但是用 0 base, 记为1
    
    long diffDayNum = 0;
    
    // 计算累加 年的天数差值
    int tmpY = baseYear;
    while(tmpY > year) {
        // 如果baseyear 比较大，逐年减小之，按平闰年累加 diffDayNum
        --tmpY;
        diffDayNum -= isLeapYear(tmpY) ? 366 : 365;
    }
    while(tmpY < year) {
        // 如果baseyear 比较小，逐年增大之，按平闰年累加 diffDayNum
        diffDayNum += isLeapYear(tmpY) ? 366 : 365;
        ++tmpY;
    }
    
    // 计算累加 月的天数差值
    int tmpM = baseMonth;
    while(tmpM < month) {
        // baseMonth 一定不大于 month
        // 逐月增加，累加月份天数到 diffDayNum
        diffDayNum += dayNumOfYear(year, tmpM);
        ++tmpM;
    }
    
    // 计算累加 日的天数差值
    diffDayNum += day-baseDay;
    
    int weekDay = (baseWeekDay + diffDayNum)%7; // 计算 0 base 星期几
    if(weekDay < 0){
        weekDay += 7;
    }
    
    weekDay += 1; // 换算成 1 base 星期几
    
    return weekDay;
}

void demoBranchLogic(void) {
    logWsBegin("demoBranchLogic begin\n");
    
    char weekStr[32] = {0};
    
    for(int y=1981; y<2071; ++y) {

        for(int m=2; m<=5; ++m) {
            int days = dayNumOfYear(y, m);
            printf("%d年%d月有%d天", y, m, days);
            
            for(int d=26; d<=31; ++d) {
                
                int weekDay = computeWeekDayOfYear(y, m, d);
                
                if (weekDay >= 0) {
                    sprintf(weekStr, "星期%d", weekDay);
                } else {
                    sprintf(weekStr, "日期无效");
                }
                printf("  %d年%d月%d日 -> %s\n", y, m, d, weekStr);
                break;
            }
            
            break;
        }
        //break;
    }

    logWs("demoBranchLogic end\n");
}